# coding: utf-8
import logging

import tornado.ioloop
import tornado.web
import json
import MySQLdb
import traceback

log = logging.getLogger(__name__)


class Index(tornado.web.RequestHandler):
    def data_received(self, chunk):
        pass

    def get(self):
        self.render('templates/index.html')


class Query(tornado.web.RequestHandler):
    def post(self):
        try:
            args = json.loads(self.request.body)
            sql = args.get('sql')
            if not sql:
                self.write({'success': False, 'message': 'miss args: sql', 'data': None})
                return

            config = json.loads(args.get('config'))
            if not config:
                self.write({'success': False, 'message': 'miss args: database config', 'data': None})
                return
        except ValueError:
            self.write({'success': False, 'message': 'The parameters of the error!', 'data': None})
            return

        try:
            db = MySQLdb.connect(**config)
            cursor = db.cursor()
            cursor.execute(sql)
            title = [d[0] for d in cursor.description]
            data = cursor.fetchall()
        except MySQLdb.MySQLError:
            logging.error(traceback.format_exc())
            self.write({'success': False, 'message': 'Database error!', 'data': None})
            return

        data = [[format(cell, '.2f') if isinstance(cell, float) else str(cell) for cell in row] for row in data]

        try:
            self.write({'success': True, 'message': None,
                        'data': {'columns': title, 'rows': [dict(zip(title, d)) for d in data]}
                        })
        except (Exception,):
            err = traceback.format_exc()
            logging.error(err)
            self.write({'success': False, 'message': err, 'data': None})


def make_app():
    return tornado.web.Application([
        (r"/", Index),
        (r"/query", Query)
    ])


if __name__ == "__main__":
    application = make_app()
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)d]  %(message)s',
                        datefmt='%a, %d %b %Y %H:%M:%S')
    application.listen(9898)
    tornado.ioloop.IOLoop.instance().start()
